package com.strato.passport.server.v1_0_0.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.strato.annotation.osgi.v1_0_0.service.OsgiWired;
import com.strato.json.v1_0_0.exec.JSONUtils;
import com.strato.logging.v1_0_0.api.Log;
import com.strato.mvc.annotation.v1_0_0.annotation.method.PathVariable;
import com.strato.mvc.annotation.v1_0_0.annotation.method.RequestMapping;
import com.strato.mvc.annotation.v1_0_0.annotation.type.Controller;
import com.strato.passport.server.v1_0_0.service.LoginCheckResult;

@Controller
@com.strato.mvc.annotation.v1_0_0.annotation.type.RequestMapping("${strato.passport.prefix}")
public class PassportController{
	
	@OsgiWired
	private Log log = null;
	
	@RequestMapping("/")
	public void index(HttpServletRequest req,HttpServletResponse resp) throws IOException{
		String redirectUrlParam=Helper.getInstance().getRedirecturlParameterName();
		String redirecturl=req.getParameter(redirectUrlParam);
		req.setAttribute(redirectUrlParam, redirecturl);
		Object user=Helper.getInstance().extractFromSession(req,resp);
		if(user!=null){
			Helper.getInstance().doRedirectOnLogin(user,req,resp);
			return;
		}
		user=Helper.getInstance().extractFromCookie(req,resp);
		if(user!=null){
			LoginCheckResult result = Helper.getInstance().check(user);
			if(result.isSuccess()){
				Helper.getInstance().onLoginSuccess(user,req,resp);
				Helper.getInstance().doRedirectOnLogin(user,req,resp);
				return;
			}
			req.setAttribute(Helper.getInstance().getLoginResultAttributName(), result);
		}
		Helper.getInstance().forwardLogin(req,resp);
	}
	
	@RequestMapping("/logout")
	public void logout(HttpServletRequest req,HttpServletResponse resp){
		HttpSession session = req.getSession();
		session.invalidate();
		Helper.getInstance().clearCookie(req,resp);
		String u=req.getParameter(Helper.getInstance().getRedirecturlParameterName());
		req.setAttribute(Helper.getInstance().getRedirecturlParameterName(), u);
		Helper.getInstance().forwardLogout(req,resp);
	}

	@RequestMapping("/check")
	public void check(HttpServletRequest req,HttpServletResponse resp) throws IOException{
		Object user=Helper.getInstance().extractFromRequest(req,resp);
		if(user!=null){
			LoginCheckResult result = Helper.getInstance().check(user);
			if(result.isSuccess()){
				Helper.getInstance().onLoginSuccess(user,req,resp);
				Helper.getInstance().doRedirectOnLogin(user,req,resp);
				return;
			}
			req.setAttribute(Helper.getInstance().getLoginResultAttributName(), result);
		}
		Helper.getInstance().forwardLogin(req,resp);
	}
	
	@RequestMapping("/validate/{ticket}")
	public void validate(@PathVariable String ticket,HttpServletRequest req,HttpServletResponse resp) throws IOException{
		String r = Helper.getInstance().validateTicket(ticket);
		if(r!=null){
			PrintWriter out = resp.getWriter();
			out.write(r);
			out.flush();
		}
	}
	
	@RequestMapping("/jsonp")
	public void jsonp(HttpServletRequest req,HttpServletResponse resp) throws IOException{
		String cb=req.getParameter(Helper.getInstance().getJsonpCallbackParameterName());
		Object user=getJsonpUser(req,resp);
		if(user!=null){
			String userJson=null;
			try {
				userJson = JSONUtils.getInstance().toJSON(user);
			} catch (Exception e) {
				log.error("Error marshalling user "+user,e);
				throw new RuntimeException(e);
			}
			resp.setContentType("text/javascript;charset=UTF-8");
			PrintWriter out = resp.getWriter();
			out.println(cb+"("+userJson+");");
		}else{
			resp.setContentType("text/javascript;charset=UTF-8");
			PrintWriter out = resp.getWriter();
			out.println(cb+"();");
		}
	}

	private Object getJsonpUser(HttpServletRequest req, HttpServletResponse resp) {
		Object user=Helper.getInstance().extractFromSession(req, resp);
		if(user!=null){
			return Helper.getInstance().desensitize(user);
		}
		user=Helper.getInstance().extractFromCookie(req,resp);
		LoginCheckResult result = Helper.getInstance().check(user);
		if(result.isSuccess()){
			return Helper.getInstance().desensitize(user);
		}
		return null;
	}
}
